
#define GCC_COMPILER

#include "gcc.h"
#include "iar.h"
#include "common.h"
#include "iom8535_user.h"

#define RF_SEL_PIN 4
#define LOOP_1_PIN 5
#define LOOP_2_PIN 6
#define ENC_A_PIN 6
#define ENC_B_PIN 7
#define ENC_BUTTON_PIN 5
#define BUTTON_1_PIN 0
#define BUTTON_2_PIN 1
#define DISPLAY_E_PIN 2
#define DISPLAY_RS_PIN 4
#define DISPLAY_RW_PIN 3

#define SW1_pressed (PORTB & 1)
#define SW2_pressed (PORTB & 2)
#define ENC_pressed (PORTC & 1<<5)
#define ENC_A_TURN  (PORTC & 1<<6)
#define ENC_B_TURN  (PORTC & 1<<7)

uint8 REG;
#define UPDATE_REG	0
#define UPDATE_TEMP	1
#define UPDATE_TIME  2
uint8 UPDATE=0;

uint8 time[9]; //seconds, minutes, hours, days, week_days, century_month, years, error_codes
uint8 const_temp;


void display_update(uint8 update_val){
;
};

#ifdef IAR_COMPILER
#pragma vector=INT0_vect
__interrupt void RF_issue(void) {
#else
	ISR(INT0_vect) {
#endif
  //check what is the issue
  //1.
  //2.
  //3.
  //4.  

};

#ifdef IAR_COMPILER
	#pragma vector=INT1_vect
	__interrupt void power_issue(void) {
#else
	ISR(INT1_vect) {
#endif
};

#ifdef IAR_COMPILER
	#pragma vector=INT2_vect
	__interrupt void key_pressed(void) {
#else
	ISR(INT2_vect){
#endif
		if (REG==2) {
			//if (SW1_pressed)
			//	;
			//else if (SW2_pressed)
			//	;
			//else if (ENC_pressed)
			//	;
			if (ENC_A_TURN && ENC_B_TURN) {
				const_temp++;
				UPDATE |= 1<<UPDATE_TEMP;
			} else if (ENC_A_TURN && !ENC_B_TURN) {
				const_temp--;
				UPDATE |= 1<<UPDATE_TEMP;
			}
		}
	};

void pcf8563_init(){
};

void rf_init() {
};

void display_goto(char raw, char col){
	char adr = raw<<4 + col;
	PORTA = 1<<7 + adr;
	UNSET_RS;
	UNSET_RW;
	SET_E;
	char tmp=0; while(tmp++ < 2){;};
	UNSET_E;
}

void display_print(int num, char * string){
	if ( wait_interval[DISPLAY_THREAD] > 0 )
		return;
	const char stack_pos = 2;
	thread_state[DISPLAY_THREAD*THREAD_STACK_SIZE + stack_pos]++;
	char stage = thread_state[DISPLAY_THREAD*THREAD_STACK_SIZE + stack_pos];
	char print_pos = stage;
	if (print_pos == num) {
		thread_state[DISPLAY_THREAD*THREAD_STACK_SIZE + stack_pos] = 255;
		return;
	}



}

uint8 display_init() {
	//wait 40 ms
	DDRA = 0xFF; //output
	DDRC |= (1<<3 | 1<<4); //output
	wait_ticks(FREQ_10ms_TICKS, FREQ_10ms_PRESC);
	wait_ticks(FREQ_10ms_TICKS, FREQ_10ms_PRESC);
	wait_ticks(FREQ_10ms_TICKS, FREQ_10ms_PRESC);
	wait_ticks(FREQ_10ms_TICKS, FREQ_10ms_PRESC);
	PORTA = 15<<2;  //00111100, two lines, 8-bit interface, 5x8 char
	UNSET_RS;
	UNSET_RW;
	SET_E;
	char tmp=0; while(tmp++ < 2){;};
	UNSET_E;
	wait_ticks(FREQ_40us_TICKS, FREQ_40us_PRESC);
	PORTA = 15; //set display, cursor, blinking
	SET_E;
	char tmp=0; while(tmp++ < 2){;};
	UNSET_E;
	PORTA= 1;
	SET_E;
	char tmp=0; while(tmp++ < 2){;};
	UNSET_E;
	wait_ticks(FREQ_1p5ms_TICKS, FREQ_1p5ms_PRESC);
	PORTA = 3;
	SET_E;
	char tmp=0; while(tmp++ < 2){;};
	UNSET_E;

	return 0;
};

#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define PCF8563_W 0xA2
#define PCF8563_R 0xA3


uint8 read_full_time(){
	time[8] = twi_start(); if (time[8]) return time[8];
	time[8] = twi_adr( PCF8563_W );  if (time[8]) return time[8];
	time[8] = twi_send_single(0x02);  if (time[8]) return time[8];
	time[8] = twi_stop();  if (time[8]) return time[8];
	time[8] = twi_start();  if (time[8]) return time[8];
	time[8] = twi_adr( PCF8563_R );   if (time[8]) return time[8];
	time[8] = twi_read(7, time);  if (time[8]) return time[8];
	time[8] = twi_stop();  if (time[8]) return time[8];
	return 0;
};

uint8 write_full_time(){
	time[8] = twi_start();  if (time[8]) return time[8];
	time[8] = twi_adr( PCF8563_W );  if (time[8]) return time[8];
	time[8] = twi_send_single(0x02);  if (time[8]) return time[8];
	time[8] = twi_stop();  if (time[8]) return time[8];
	time[8] = twi_start();  if (time[8]) return time[8];
	time[8] = twi_adr( PCF8563_W );   if (time[8]) return time[8];
	time[8] = twi_send(7, time);  if (time[8]) return time[8];
	time[8] = twi_stop();  if (time[8]) return time[8];
	return 0;
};

void do_constant_loop() {
	const char stack_pos = 0;
	;
	//check if display update needed
	//check if time update_needed
}

int main( void )
{
  //init of timer pcf8563
  REG=0;
  uint8 i = 0;
  while(i < NUM_THREADS){
	  wait_interval[i] = 0; i++;
  }
  twi_init();
  pcf8563_init();
  time[8] = 0;
  const_temp = 23;
  read_full_time();
  //init of display 
  display_init();
  //init of RF module
  rf_init();
  //setting the timer to read the clock data
  //set_timer();
  timers_init();

  for (char i=0; i< THREAD_STACK_SIZE*NUM_THREADS; i++)
	  thread_state[i] = 255;

  while(1)
	  do_constant_loop();
  
  
  
  return 0;
}
